/**
 * @file dev.h
 * @author lcz (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-11-06
 *
 * @copyright Copyright (c) 2022
 *
 */

#ifndef DEV_H
#define DEV_H
#define DEV_NAME_SIZE 32 // 设备名称长度
// 设备类型
enum
{
    DEV_UNKNOWN = 0, // 未知类型
    DEV_TTY,         // TTY设备
    DEV_DISK,        // 磁盘设备
};

struct _dev_desc_t;
/**
 * @brief 设备驱动接口
 */
typedef struct _device_t
{
    struct _dev_desc_t *desc; // 设备特性描述符
    int mode;                 // 操作模式
    int minor;                // 次设备号
                                // 主设备及次设备号确定一种具体的设备
    void *data;     // 设备参数
    int open_count; // 打开次数
} device_t;

// 某一种类型的设备
/**
 * @brief 设备描述结构
 */
typedef struct _dev_desc_t
{
    char name[DEV_NAME_SIZE]; // 设备名称
    int major;                // 主设备号
    // 例如 对于磁盘，我们将打开的磁盘的函数对其赋值
    // 不同的设备我们使用相同的设备函数，具体函数交由驱动程序实现，该函数指针指向驱动程序
    int (*open)(device_t *dev);
    int (*read)(device_t *dev, int addr, char *buf, int size);
    int (*write)(device_t *dev, int addr, char *buf, int size);
    int (*control)(device_t *dev, int cmd, int arg0, int arg1);
    int (*close)(device_t *dev);
} dev_desc_t;

static int is_devid_bad(int dev_id);
int dev_open(int major, int minor, void *data);
int dev_read(int dev_id, int addr, char *bug, int size);
int dev_write(int dev_id, int addr, char *buf, int size);
int dev_control(int dev_id, int cmd, int arg0, int arg1);
void dev_close(int dev_id);
#endif //